package com.shujuwuliankeji.ems.cloud.module.bussiness.controller;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.shujuwuliankeji.ems.cloud.common.core.utils.DateUtils;
import com.shujuwuliankeji.ems.cloud.common.core.utils.StringUtils;
import com.shujuwuliankeji.ems.cloud.common.core.web.controller.BaseController;
import com.shujuwuliankeji.ems.cloud.common.core.web.domain.AjaxResult;
import com.shujuwuliankeji.ems.cloud.module.bussiness.constant.OneMsgType;
import com.shujuwuliankeji.ems.cloud.module.bussiness.domain.*;
import com.shujuwuliankeji.ems.cloud.module.bussiness.domain.OneNetData.HttpParams;
import com.shujuwuliankeji.ems.cloud.module.bussiness.domain.OneNetData.MsgData;
import com.shujuwuliankeji.ems.cloud.module.bussiness.domain.vo.OneReceive;
import com.shujuwuliankeji.ems.cloud.module.bussiness.service.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;


import javax.annotation.PostConstruct;
import javax.crypto.*;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.*;

@RestController
@RequestMapping("/receive")
public class BaseReceiveController extends BaseController {

    private Logger log = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private IOneReceiveService oneReceiveService;

    @Autowired
    private IOneReceiveMsgService oneReceiveMsgService;

    @Autowired
    private IBussDeviceService iBussDeviceService;

    @Autowired
    private IBussDeviceAmmeterDataService iBussDeviceAmmeterDataService;

    @Autowired
    private IBussDeviceAmmeterWarningRulesService bussDeviceAmmeterWarningRulesService;

    @Autowired
    private IBussDeviceAmmeterWarningService bussDeviceAmmeterWarningService;

    /**
     * 中台验证接口
     * @param msg
     * @param nonce
     * @param signature
     * @return
     */
    @GetMapping("/data")
    public String receive(@RequestParam("msg") String msg,
                              @RequestParam("nonce") String nonce,
                              @RequestParam("signature") String signature){
        log.info("中台http推送接口验证成功");
        return msg;
    }

    /**
     * 中台明文方式推送的数据
     * @param body
     * @return
     */
    @PostMapping("/data")
    public AjaxResult receive(@RequestBody HttpParams body) throws NoSuchFieldException, IllegalAccessException {
        log.info("中台明文方式推送,数据:{}",  body.toString());
        OneReceive oneReceive=new OneReceive(body);
        oneReceiveService.insertOneReceive(oneReceive);
        System.out.println(new Date());
        String msg=body.getMsg();
        MsgData msgData = JSON.parseObject(msg, MsgData.class);
        OneReceiveMsg oneReceiveMsg=new OneReceiveMsg(msgData);
        oneReceiveMsg.setOneReceiveId(oneReceive.getId());
        oneReceiveMsgService.insertOneReceiveMsg(oneReceiveMsg);
        if(OneMsgType.NOTIFY.equals(oneReceiveMsg.getMessageType())){
            dealData(oneReceiveMsg);
        }
        return AjaxResult.success();
    }






    /**
     *对接电表数据到数据库
     */
    @GetMapping("/deal")
    public void dealData(OneReceiveMsg oneReceiveMsg) throws NoSuchFieldException, IllegalAccessException {
       /* OneReceiveMsg oneReceiveMsgParam=new OneReceiveMsg();
        oneReceiveMsgParam.setId(12L);
        OneReceiveMsg oneReceiveMsg= oneReceiveMsgService.selectOneReceiveMsgById(oneReceiveMsgParam);*/
        String deviceName = oneReceiveMsg.getDeviceName();
        //查询本地设备信息
        BussDevice bussDeviceParam=new BussDevice();
        bussDeviceParam.setDeviceName(deviceName);
        bussDeviceParam.setCompanyId(11L);
        List<BussDevice> bussDevices = iBussDeviceService.selectBussDeviceList(bussDeviceParam);
        Long deviceId = bussDevices.get(0).getId();
        //项目id
        Long projectId=bussDevices.get(0).getProjectId();
        //解析数据
        String data = oneReceiveMsg.getData();
        JSONObject jsonObject = JSON.parseObject(data);
        HashMap<String, JSONObject> params = (HashMap)jsonObject.get("params");
        //业务平台与中台电表字段对应关系
        HashMap<String,String> relateMap=new HashMap<String,String>(){{
            this.put("Ct","");//电流变比
            this.put("DI2","");//数字量输入2状态
            this.put("DI3","");//数字量输入3状态
            this.put("DI4","");//数字量输入4状态
            this.put("DO1","");//数字量输出1状态
            this.put("DO2","");//数字量输出2状态
            this.put("EP","");//组合有功总电能
            this.put("EPneg","");//反向有功电能
            this.put("EPpos","");//正向有功电能
            this.put("EQneg","");//反向无功电能
            this.put("EQpos","");//正向无功电能
            this.put("F","f");//电源频率
            this.put("IA","ia");//A相电流---
            this.put("IB","ib");//B相电流---
            this.put("IC","ic");//C相电流---
            this.put("OnlineState","");//在线状态
            this.put("PFA","cosa");//A相功率因数
            this.put("PFB","cosb");//B相功率因数
            this.put("PFC","cosc");//C相功率因数
            this.put("PT","p");//总有功功率
            this.put("Pa","pa");//A相有功功率
            this.put("Pb","pb");//B相有功功率
            this.put("Pc","pc");//C相有功功率
            this.put("Pf","cosq");//总功率因数
            this.put("Pt","");//电压变比
            this.put("QA","qa");//A相无功功率
            this.put("QB","qb");//B相无功功率
            this.put("QC","qc");//C相无功功率
            this.put("QT","q");//总无功功率

            this.put("SA","sa");//A相视在功率
            this.put("SB","sb");//B相视在功率
            this.put("SC","sc");//C相视在功率
            this.put("ST","s");//总视在功率
            this.put("UA","ua");//A相电压
            this.put("UAB","uab");//AB线电压
            this.put("UB","ub");//B相电压
            this.put("UBC","ubc");//BC线电压
            this.put("UC","uc");//C相电压
            this.put("UCA","uac");//CA线电压
            this.put("UpdateTime","");//上传时间
        }};

        //根据报警规则  是否生成报警信息
        BussDeviceAmmeterWarningRules bussRulesParam=new BussDeviceAmmeterWarningRules();
        bussRulesParam.setCompanyId(11L);
        bussRulesParam.setProjectId(projectId);
        bussDeviceParam.setStatus(1);
        List<BussDeviceAmmeterWarningRules> bussRules = bussDeviceAmmeterWarningRulesService.selectBussDeviceAmmeterWarningRulesList(bussRulesParam);

        BussDeviceAmmeterData bussDeviceAmmeterData=new BussDeviceAmmeterData();
        for(Map.Entry<String, JSONObject> entry : params.entrySet()){
            System.out.println("key="+entry.getKey()+"  value="+entry.getValue());
            String key=entry.getKey();
            String s = relateMap.get(key);
            if(StringUtils.isNotEmpty(s)){
                JSONObject jsonObject1 = JSON.parseObject(entry.getValue().toString());
                String value = jsonObject1.get("value").toString();
                Field fieldObj = bussDeviceAmmeterData.getClass().getDeclaredField(s);
                fieldObj.setAccessible(true);
                fieldObj.set(bussDeviceAmmeterData, new BigDecimal(value));
                for(BussDeviceAmmeterWarningRules rule:bussRules){
                    String conditionPro=rule.getConditionProperty();
                    String condition=rule.getCondition();
                    BigDecimal conditionValue=rule.getConditionValue();
                    if(s.equals(conditionPro)){

                        BussDeviceAmmeterWarning bussWarning=new BussDeviceAmmeterWarning();
                        bussWarning.setCompanyId(11L);
                        bussWarning.setDeviceId(deviceId);
                        bussWarning.setProjectId(projectId);
                        //报警事件类型对应关系
                        HashMap<String,String> typeMap=new HashMap<String,String>(){{
                            this.put("0","离线");
                            this.put("1","过压");
                            this.put("2","过流");
                        }};
                        //String info=typeMap.get(rule.getEventType().toString());

                        bussWarning.setEventType(rule.getEventType());
                        bussWarning.setIsRead(0);
                        BigDecimal current=new BigDecimal(value);
                        switch (condition){
                            case OneMsgType.GREATER_THAN_OR_EQUAL:
                                if(current.compareTo(conditionValue)>=0){
                                    bussWarning.setEventInfo("大于等于设置的触发值");
                                    bussDeviceAmmeterWarningService.insertBussDeviceAmmeterWarning(bussWarning);
                                }
                                break;
                            case OneMsgType.LESS_THAN_OR_EQUAL:
                                if(current.compareTo(conditionValue)<=0){
                                    bussWarning.setEventInfo("小于等于设置的触发值");
                                    bussDeviceAmmeterWarningService.insertBussDeviceAmmeterWarning(bussWarning);
                                }
                                break;
                            case OneMsgType.GREATER_THAN:
                                if(current.compareTo(conditionValue)>0){
                                    bussWarning.setEventInfo("大于设置的触发值");
                                    bussDeviceAmmeterWarningService.insertBussDeviceAmmeterWarning(bussWarning);
                                }
                                break;
                            case OneMsgType.LESS_THAN:
                                if(current.compareTo(conditionValue)<0){
                                    bussWarning.setEventInfo("小于设置的触发值");
                                    bussDeviceAmmeterWarningService.insertBussDeviceAmmeterWarning(bussWarning);
                                }
                                break;
                            case OneMsgType.EQUAL:
                                if(current.compareTo(conditionValue)==0){
                                    bussWarning.setEventInfo("等于设置的触发值");
                                    bussDeviceAmmeterWarningService.insertBussDeviceAmmeterWarning(bussWarning);
                                }
                                break;
                            default:
                                break;
                        }
                    }
                }
            }
        }
        bussDeviceAmmeterData.setCreateTime(DateUtils.getNowDate());
        bussDeviceAmmeterData.setDeviceId(deviceId);
        iBussDeviceAmmeterDataService.insertBussDeviceAmmeterData(bussDeviceAmmeterData);
    }

    @PostConstruct
    void started() {
        TimeZone.setDefault(TimeZone.getTimeZone("GMT+8"));
    }



    @GetMapping("/datas")
    public String receives(@RequestParam("msg") String msg,
                          @RequestParam("nonce") String nonce,
                          @RequestParam("signature") String signature){
        System.out.println(msg);
        return msg;
    }

    @PostMapping("/datas")
    public void receives(@RequestBody HttpParams body){
        System.out.println("222222222222");
        System.out.println(body.toString());
        String msg=body.getMsg();
        System.out.println(msg);

    }

    @GetMapping("/three")
    public String receives3(@RequestParam("msg") String msg,
                           @RequestParam("nonce") String nonce,
                           @RequestParam("signature") String signature){
        System.out.println(msg);
        return msg;
    }

    @PostMapping("/three")
    public void receives3(@RequestBody HttpParams body){
        System.out.println("333333");
        System.out.println(body.toString());
        String msg=body.getMsg();
        System.out.println(msg);

    }


    /**
     * 功能描述 推送消息解密
     *
     * @param encryptMsg 加密消息体对象
     * @param key        配置页面生成的AES秘钥
     * @return
     * @throws NoSuchPaddingException
     * @throws NoSuchAlgorithmException
     * @throws InvalidAlgorithmParameterException
     * @throws InvalidKeyException
     * @throws BadPaddingException
     * @throws IllegalBlockSizeException
     */
    public static String decrypt(String encryptMsg, byte[] key) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidAlgorithmParameterException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
        byte[] encMsg = Base64.getDecoder().decode(encryptMsg);
        SecretKey secretKey = new SecretKeySpec(key, "AES");
        //算法/模式/补码方式
        //CBC模式 向量必须是16个字节
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
        cipher.init(Cipher.DECRYPT_MODE, secretKey, new IvParameterSpec(key));
        byte[] msg = cipher.doFinal(encMsg);
        return new String(msg);
    }
}
